const crypto = require('crypto');
const { checkSchema, validationResult } = require('express-validator')
const { registerUser } = require('../service/user');


// 登录验证信息
const loginValidator = () => {
  return checkSchema({
    username: {
      isLength: {
        options: { min: 5 },
        errorMessage: 'Username must be at least 5 chars long'
      },
      trim: true
    },
    password: {
      isLength: {
        errorMessage: 'Password must be at least 5 chars long'
      },
      trim: true
    }
  })
}

// 注册验证信息
const registerValidator = () => {
  return checkSchema({
    name: {
      notEmpty: {
        errorMessage: 'Name is required'
      },
      isLength: {
        options: { min: 2, max: 50 },
        errorMessage: 'Name must be between 2 and 50 chars long'
      },
      trim: true
    },
    email: {
      notEmpty: {
        errorMessage: 'Email is required'
      },
      isEmail: {
        errorMessage: 'Please provide a valid email address'
      },
      normalizeEmail: true,
      trim: true
    },
    username: {
      notEmpty: {
        errorMessage: 'Username is required'
      },
      isLength: {
        options: { min: 5, max: 30 },
        errorMessage: 'Username must be between 5 and 30 chars long'
      },
      matches: {
        options: /^[a-zA-Z0-9_]+$/,
        errorMessage: 'Username can only contain letters, numbers and underscores'
      },
      trim: true
    },
    password: {
      notEmpty: {
        errorMessage: 'Password is required'
      },
    },
    password2: {
      notEmpty: {
        errorMessage: 'Please confirm your password'
      },
      custom: {
        options: (value, { req }) => {
          if (value !== req.body.password) {
            throw new Error('Passwords do not match');
          }
          return true;
        }
      }
    }
  })
}

// 验证结果处理中间件（保留用于向后兼容）
const handleValidationErrors = (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    // 如果有错误，重新渲染表单并显示错误信息
    return res.render('register', {
      title: 'Register',
      errors: errors.array(),
      formData: req.body // 保留用户输入的数据
    });
  }
  next();
}

// 🚀 高阶函数：通用的校验和错误处理（推荐使用）
// 用法：router.post('/register', ...validateAndHandle(registerValidator, 'register'), handler)
const validateAndHandle = (validator, view) => {
  return [
    validator(),
    (req, res, next) => {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.render(view, {
          title: view.charAt(0).toUpperCase() + view.slice(1),
          errors: errors.array(),
          formData: req.body
        });
      }
      next();
    }
  ];
};


/**
 * 验证密码是否正确
 * @param {string} inputPassword - 用户输入的明文密码
 * @param {string} storedPassword - 数据库中存储的加密密码（十六进制字符串）
 * @param {string} storedSalt - 数据库中存储的盐值（十六进制字符串）
 * @returns {boolean} - 密码是否匹配
 */
const verifyPassword = (inputPassword, storedPassword, storedSalt) => {
  try {
    // 将十六进制字符串转换回 Buffer
    const saltBuffer = Buffer.from(storedSalt, 'hex');

    // 使用相同的参数加密输入的密码
    const hashedInputBuffer = crypto.pbkdf2Sync(inputPassword, saltBuffer, 310000, 32, 'sha256');
    const hashedInput = hashedInputBuffer.toString('hex');

    // 使用时间安全的比较方法（防止时序攻击）
    return crypto.timingSafeEqual(
      Buffer.from(hashedInput, 'hex'),
      Buffer.from(storedPassword, 'hex')
    );
  } catch (error) {
    console.error('Password verification error:', error);
    return false;
  }
};

const login = ({ name, email }) => {
  return { name, email }
}

const register = async (user, next) => {

  try {
    // 生成随机 salt（Buffer）
    const salt = crypto.randomBytes(16);

    // 使用 pbkdf2 加密密码（返回 Buffer）
    const hashedPasswordBuffer = crypto.pbkdf2Sync(user.password, salt, 310000, 32, 'sha256');

    // ⚠️ 重要：将 Buffer 转换为十六进制字符串，才能存入数据库
    const hashedPassword = hashedPasswordBuffer.toString('hex'); // 64个字符的十六进制字符串
    const saltString = salt.toString('hex'); // 32个字符的十六进制字符串

    console.log('user', user);
    console.log('hashedPassword (hex):', hashedPassword, 'length:', hashedPassword.length);
    console.log('salt (hex):', saltString, 'length:', saltString.length);

    const userid = await registerUser({ ...user, password: hashedPassword, salt: saltString });

    return next(null, userid);

  } catch (error) {
    return next(error);
  }
}

module.exports = {
  login,
  register,
  verifyPassword,
  loginValidator,
  registerValidator,
  handleValidationErrors,
  validateAndHandle
}
